package org.juggers.domain;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
 * @author <a href="mailto:nicolas@breizhjug.org">Nicolas De loof</a>
 * @author <a href="mailto:michel@breizhjug.org">Michel DAVID</a>
 */
@Entity( name = "org.juggers.domain.Event" )
public class Event
    extends AbstractEntity
{

    private static final long serialVersionUID = 1824925011241004705L;

    @Id
    @GeneratedValue( strategy = GenerationType.IDENTITY )
    private Long id;

    private String title;

    private String logo;

    private Collection<String> speakers = new ArrayList<String>();

    private Long organizerId;

    private Date dateTime;

    private String summary;

    private Date registrationStart;

    private Date registrationEnd;

    private Integer max;

    private String place;

    private Set<Long> participantsId = new HashSet<Long>();

    /**
     * @return the id
     */
    public Long getId()
    {
        return this.id;
    }

    /**
     * @param id the id to set
     */
    public void setId( Long id )
    {
        Long oldValue = this.id;
        this.id = id;
        firePropertyChange( "id", oldValue, id );
    }

    /**
     * @return the title
     */
    public String getTitle()
    {
        return this.title;
    }

    /**
     * @param title the title to set
     */
    public void setTitle( String title )
    {
        String oldValue = this.title;
        this.title = title;
        firePropertyChange( "title", oldValue, title );
    }

    /**
     * @return the logo
     */
    public String getLogo()
    {
        return this.logo;
    }

    /**
     * @param logo the logo to set
     */
    public void setLogo( String logo )
    {
        String oldValue = this.logo;
        this.logo = logo;
        firePropertyChange( "logo", oldValue, logo );
    }

    /**
     * @return the speakers
     */
    public Collection<String> getSpeakers()
    {
        return this.speakers;
    }

    /**
     * @param speakers the speakers to set
     */
    public void setSpeakers( Collection<String> speakers )
    {
        Collection<String> oldValue = this.speakers;
        this.speakers = speakers;
        firePropertyChange( "speakers", oldValue, speakers );
    }

    /**
     * @return the participantsId
     */
    public Collection<Long> getParticipantsId()
    {
        return participantsId;
    }

    /**
     * @param participantsId the participantsId to set
     */
    public void setParticipantsId( Set<Long> participantsId )
    {
        Collection<Long> oldValue = this.participantsId;
        this.participantsId = participantsId;
        firePropertyChange( "participantsId", oldValue, participantsId );
    }

    /**
     * @return the organizerId
     */
    public Long getOrganizerId()
    {
        return this.organizerId;
    }

    /**
     * @param organizerId the organizerId to set
     */
    public void setOrganizerId( Long organizerId )
    {
        Long oldValue = this.organizerId;
        this.organizerId = organizerId;
        firePropertyChange( "organizerId", oldValue, organizerId );
    }

    /**
     * @return the dateTime
     */
    public Date getDateTime()
    {
        return this.dateTime;
    }

    /**
     * @param dateTime the dateTime to set
     */
    public void setDateTime( Date dateTime )
    {
        Date oldValue = this.dateTime;
        this.dateTime = dateTime;
        firePropertyChange( "dateTime", oldValue, dateTime );
    }

    /**
     * @return the summary
     */
    public String getSummary()
    {
        return this.summary;
    }

    /**
     * @param summary the summary to set
     */
    public void setSummary( String summary )
    {
        String oldValue = this.summary;
        this.summary = summary;
        firePropertyChange( "summary", oldValue, summary );
    }

    /**
     * @return the registrationStart
     */
    public Date getRegistrationStart()
    {
        return this.registrationStart;
    }

    /**
     * @param registrationStart the registrationStart to set
     */
    public void setRegistrationStart( Date registrationStart )
    {
        Date oldValue = this.registrationStart;
        this.registrationStart = registrationStart;
        firePropertyChange( "registrationStart", oldValue, registrationStart );
    }

    /**
     * @return the registrationEnd
     */
    public Date getRegistrationEnd()
    {
        return this.registrationEnd;
    }

    /**
     * @param registrationEnd the registrationEnd to set
     */
    public void setRegistrationEnd( Date registrationEnd )
    {
        Date oldValue = this.registrationEnd;
        this.registrationEnd = registrationEnd;
        firePropertyChange( "registrationEnd", oldValue, registrationEnd );
    }

    /**
     * @return the max
     */
    public Integer getMax()
    {
        return this.max;
    }

    /**
     * @param max the max to set
     */
    public void setMax( Integer max )
    {
        Integer oldValue = this.max;
        this.max = max;
        firePropertyChange( "max", oldValue, max );
    }

    /**
     * @return the place
     */
    public String getPlace()
    {
        return place;
    }

    /**
     * @param place the place to set
     */
    public void setPlace( String place )
    {
        String oldValue = this.place;
        this.place = place;
        firePropertyChange( "place", oldValue, place );
    }

    /**
     * Subscribe to event
     * 
     * @param jugger Jugger
     */
    public void subscribe( Jugger jugger )
        throws NotEnoughSeatsException, AlreadySubscribedException
    {
        if ( participantsId.contains( jugger.getId() ) )
        {
            throw new AlreadySubscribedException();
        }
        if ( participantsId.size() >= max )
        {
            throw new NotEnoughSeatsException();
        }

        Set<Long> participantsId = new HashSet<Long>( this.participantsId );
        participantsId.add( jugger.getId() );
        setParticipantsId( participantsId );
    }

    /**
     * Unsubscribe to event
     * 
     * @param jugger Jugger
     */
    public void unsubscribe( Jugger jugger )
        throws NotSubscribedException
    {
        if ( !participantsId.contains( jugger.getId() ) )
        {
            throw new NotSubscribedException();
        }

        Set<Long> participantsId = new HashSet<Long>( this.participantsId );
        participantsId.remove( jugger.getId() );
        setParticipantsId( participantsId );
    }

    
    // Fonzie methods
    public native void persist() /*-{

    }-*/;

    public native void refresh() /*-{

    }-*/;

    public native Event merge() /*-{

    }-*/;

    public native void remove() /*-{

    }-*/;

    public native static Collection<Event> findAll(int maxResults) /*-{

    }-*/;
    
    public native static Event findById(Long id) /*-{

    }-*/;

    public native static Collection<Event> findByOrganizerId(Long organizerId) /*-{

    }-*/;
}
